package social.hub.impl.jersey.api;

import static social.hub.api.twitter.TwitterConstants.*;

import java.util.List;
import java.util.Map;

import social.hub.api.ApiConfig;
import social.hub.api.twitter.Tweet;
import social.hub.api.twitter.TwitterApi;
import social.hub.api.twitter.TwitterProfile;
import social.hub.impl.jersey.util.ClientFactory;
import social.hub.util.UrlBuilder;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.GenericType;

public class JerseyTwitterApi implements TwitterApi {

	private GenericType<Map<String, Object>> MAP_TYPE = new GenericType<Map<String, Object>>() {
	};

	private GenericType<List<TwitterProfile>> TWITTER_PROFILE_LIST_TYPE = new GenericType<List<TwitterProfile>>() {
	};

	private GenericType<List<Tweet>> TWEET_LIST_TYPE = new GenericType<List<Tweet>>() {
	};

	private final Client client;

	public JerseyTwitterApi(ApiConfig config) {
		client = ClientFactory.createClient(config);
	}

	@Override
	public List<TwitterProfile> getFollowers() {
		return getFollowers(getProfileId());
	}

	@Override
	public List<TwitterProfile> getFollowers(String twitterId) {

		String url = buildUrl(STATUSES_FOLLOWERS_URL, twitterId);

		return client.resource(url).get(TWITTER_PROFILE_LIST_TYPE);

	}

	@Override
	public List<TwitterProfile> getFriends() {
		return getFriends(getProfileId());
	}

	@Override
	public List<TwitterProfile> getFriends(String twitterId) {

		String url = buildUrl(STATUSES_FRIENDS_URL, twitterId);

		return client.resource(url).get(TWITTER_PROFILE_LIST_TYPE);

	}

	@Override
	public List<Tweet> getFriendsTimeline() {

		String twitterId = getProfileId();

		String url = buildUrl(FRIENDS_TIMELINE_URL, twitterId);

		return client.resource(url).get(TWEET_LIST_TYPE);

	}

	@Override
	public List<Tweet> getHomeTimeline() {

		String twitterId = getProfileId();

		String url = buildUrl(HOME_TIMELINE_URL, twitterId);

		return client.resource(url).get(TWEET_LIST_TYPE);

	}

	@Override
	public List<Tweet> getPublicTimeline() {

		String twitterId = getProfileId();

		String url = buildUrl(PUBLIC_TIMELINE_URL, twitterId);

		return client.resource(url).get(TWEET_LIST_TYPE);

	}

	@Override
	public String getProfileId() {

		String url = buildUrl(VERIFY_CREDENTIALS_URL).toString();

		Map<String, Object> response = client.resource(url).get(MAP_TYPE);

		return String.valueOf(response.get("id_str").toString());

	}

	@Override
	public TwitterProfile getProfile() {
		return getProfile(getProfileId());
	}

	@Override
	public TwitterProfile getProfile(String twitterId) {

		String url = buildUrl(USER_SHOW_URL, twitterId);

		return client.resource(url).get(TwitterProfile.class);

	}

	@Override
	public List<Tweet> getUserTimeline() {
		return getUserTimeline(getProfileId());
	}

	@Override
	public List<Tweet> getUserTimeline(String twitterId) {

		String url = buildUrl(USER_TIMELINE_URL, twitterId);

		return client.resource(url).get(TWEET_LIST_TYPE);

	}

	@Override
	public void retweet(String tweetId) {

		String url = buildUrl(STATUSES_RETWEET_URL).addQueryParan("tweet_id", tweetId).toString();

		client.resource(url).post();

	}

	@Override
	public void sendDirectMessage(String text, String toTwitterId) {

		String url = buildUrl(DIRECT_MESSAGE_SEND_URL).addQueryParan("user_id", toTwitterId)
				.addQueryParan("text", text).toString();

		client.resource(url).post();

	}

	@Override
	public void updateStatus(String status) {

		String url = buildUrl(DIRECT_MESSAGE_SEND_URL).addQueryParan("status", status).toString();

		client.resource(url).post();

	}

	private UrlBuilder buildUrl(String baseUrl) {
		return new UrlBuilder(baseUrl).addUrlParan("format", "json");
	}

	private String buildUrl(String baseUrl, String twitterId) {
		return buildUrl(baseUrl).addQueryParan("user_id", twitterId).toString();
	}

}
